package core

import (
	"bytes"
	"encoding/json"
	"fmt"
	"io"
	"net/http"
	"time"

	"jlpay-sdk-go/pkg/jlpay/utils"
)

// HttpClient HTTP请求客户端接口
type HttpClient interface {
	// Execute 执行HTTP请求
	Execute(request *HttpRequest) (*HttpResponse, error)
}

// HttpRequest HTTP请求
type HttpRequest struct {
	// URL 请求URL
	URL string
	// Method 请求方法，例如：GET, POST
	Method string
	// Headers 请求头
	Headers map[string]string
	// Body 请求体
	Body interface{}
}

// HttpResponse HTTP响应
type HttpResponse struct {
	// StatusCode HTTP状态码
	StatusCode int
	// Headers 响应头
	Headers map[string]string
	// Body 响应体
	Body string
}

// DefaultHttpClient 默认HTTP客户端实现
type DefaultHttpClient struct {
	client *http.Client
}

// NewDefaultHttpClient 创建默认HTTP客户端
func NewDefaultHttpClient(connectTimeout, readTimeout time.Duration) *DefaultHttpClient {
	return &DefaultHttpClient{
		client: &http.Client{
			Transport: &http.Transport{
				// 可以根据需要配置Transport参数
			},
			Timeout: readTimeout,
		},
	}
}

// Execute 执行HTTP请求
func (c *DefaultHttpClient) Execute(request *HttpRequest) (*HttpResponse, error) {
	var reqBody io.Reader
	var reqBodyStr string
	if request.Body != nil {
		jsonData, err := json.Marshal(request.Body)
		if err != nil {
			return nil, fmt.Errorf("序列化请求体失败: %w", err)
		}
		reqBody = bytes.NewBuffer(jsonData)
		reqBodyStr = string(jsonData)
	}

	req, err := http.NewRequest(request.Method, request.URL, reqBody)
	if err != nil {
		return nil, fmt.Errorf("创建HTTP请求失败: %w", err)
	}

	// 设置请求头
	for key, value := range request.Headers {
		req.Header.Set(key, value)
	}

	// 打印请求信息
	utils.Debugf("请求URL: %s", request.URL)
	utils.Debugf("请求方法: %s", request.Method)
	utils.Debugf("请求头: %v", request.Headers)
	if reqBodyStr != "" {
		utils.Debugf("请求体: %s", reqBodyStr)
	}

	// 执行请求
	resp, err := c.client.Do(req)
	if err != nil {
		return nil, fmt.Errorf("执行HTTP请求失败: %w", err)
	}
	defer resp.Body.Close()

	// 读取响应体
	bodyBytes, err := io.ReadAll(resp.Body)
	if err != nil {
		return nil, fmt.Errorf("读取响应体失败: %w", err)
	}
	bodyString := string(bodyBytes)

	// 处理响应头
	headers := make(map[string]string)
	for key, values := range resp.Header {
		if len(values) > 0 {
			headers[key] = values[0]
		}
	}

	// 打印响应信息
	utils.Debugf("响应状态码: %d", resp.StatusCode)
	utils.Debugf("响应头: %v", headers)
	utils.Debugf("响应体: %s", bodyString)

	// 构建响应
	response := &HttpResponse{
		StatusCode: resp.StatusCode,
		Headers:    headers,
		Body:       bodyString,
	}

	return response, nil
}
